﻿using Furion.DependencyInjection;
using Furion.DynamicApiController;
using Furion.JsonSerialization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Caching.Distributed;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using tlBasic.Core;

namespace tlBasic.Application 
{
    public class SysCacheService : ISysCacheService, IDynamicApiController, ISingleton
    {
        private readonly IDistributedCache _cache;

        public SysCacheService(IDistributedCache cache)
        {
            _cache = cache;
        } 
        /// <summary>
        /// 增加对象缓存
        /// </summary>
        /// <param name="cacheKey"></param>
        /// <param name="value"></param>
        /// <returns></returns> 
        public void SetObject(string cacheKey, object value)
        {
            _cache.Set(cacheKey, Encoding.UTF8.GetBytes(JSON.Serialize(value)));
            AddCacheKey(cacheKey);
        }
        /// <summary>
        /// 增加对象缓存,并设置过期时间
        /// </summary>
        /// <param name="cacheKey"></param>
        /// <param name="value"></param>
        /// <param name="expire"></param>
        /// <returns></returns> 
        public void SetObject(string cacheKey, object value, TimeSpan expire)
        {
             _cache.Set(cacheKey, Encoding.UTF8.GetBytes(JSON.Serialize(value)), new DistributedCacheEntryOptions() { AbsoluteExpirationRelativeToNow = expire });
            AddCacheKey(cacheKey);
        }

        /// <summary>
        /// 增加字符串缓存
        /// </summary>
        /// <param name="cacheKey"></param>
        /// <param name="value"></param>
        /// <returns></returns> 
        public void SetString(string cacheKey, string value)
        {
             _cache.SetString(cacheKey, value);
             AddCacheKey(cacheKey);

        }

        /// <summary>
        /// 增加字符串缓存,并设置过期时间
        /// </summary>
        /// <param name="cacheKey"></param>
        /// <param name="value"></param>
        /// <param name="expire"></param>
        /// <returns></returns> 
        public  void SetString(string cacheKey, string value, TimeSpan expire)
        {
           _cache.SetString(cacheKey, value, new DistributedCacheEntryOptions() { AbsoluteExpirationRelativeToNow = expire });
            AddCacheKey(cacheKey);
          
        }

        /// <summary>
        /// 获取缓存
        /// </summary>
        /// <param name="cacheKey"></param>
        /// <returns></returns> 
        public string GetString(string cacheKey)
        {
            return   _cache.GetString(cacheKey);
        }

        /// <summary>
        /// 删除缓存
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns> 
        public void Remove(string key)
        {
             _cache.Remove(key); 
            DelCacheKey(key);
        }
         
        /// <summary>
        /// 获取缓存
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="cacheKey"></param>
        /// <returns></returns>
        [NonAction]
        public T Get<T>(string cacheKey)
        {
            var res =  _cache.Get(cacheKey);
            return res == null ? default : JSON.Deserialize<T>(Encoding.UTF8.GetString(res));
        }

        /// <summary>
        /// 检查给定 key 是否存在
        /// </summary>
        /// <param name="cacheKey">键</param>
        /// <returns></returns>
        [NonAction]
        public  bool Exists(string cacheKey)
        {
            var res =  _cache.Get(cacheKey);
            return res != null;
        }  
      
        /// <summary>
        /// 获取权限缓存（按钮）
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>
        [NonAction]
        public List<string> GetPermission(long userId)
        {
            var cacheKey = CacheConst.KeyPermission + userId;
            var res =  _cache.GetString(cacheKey);
            return string.IsNullOrWhiteSpace(res) ? null : JSON.Deserialize<List<string>>(res);
        }
        /// <summary>
        /// 清除权限缓存（按钮）
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>
        [NonAction]
        public void ClearPermission(long userId)
        {
            var cacheKey = CacheConst.KeyPermission + userId;
             _cache.Remove(cacheKey);
            DelCacheKey(cacheKey);
        }
        /// <summary>
        /// 缓存权限
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="permissions"></param>
        /// <returns></returns>
        [NonAction]
        public void SetPermission(long userId, List<string> permissions)
        {
            var cacheKey = CacheConst.KeyPermission + userId;
            _cache.SetString(cacheKey, JSON.Serialize(permissions));
            AddCacheKey(cacheKey);
        
        }
        /// <summary>
        /// 设置token失效时间戳
        /// </summary>
        /// <param name="userId"></param>
        /// <exception cref="NotImplementedException"></exception>
        public void SetTokenChange(long userId)
        {
            var cacheKey = CacheConst.KeyTokenChange + userId;
            _cache.SetString(cacheKey, DateTimeOffset.UtcNow.ToUnixTimeMilliseconds().ToString());

        }

        /// <summary>
        /// 增加缓存Key
        /// </summary>
        /// <param name="cacheKey"></param>
        /// <returns></returns>
        [NonAction]
        public void AddCacheKey(string cacheKey)
        {
            var res =  _cache.GetString(CacheConst.KeyAll);
            var allkeys = string.IsNullOrWhiteSpace(res) ? new List<string>() : JSON.Deserialize<List<string>>(res);
            if (!allkeys.Any(m => m == cacheKey))
            {
                allkeys.Add(cacheKey);
                _cache.SetString(CacheConst.KeyAll, JSON.Serialize(allkeys));
            }
        }

        /// <summary>
        /// 删除缓存key
        /// </summary>
        /// <param name="cacheKey"></param>
        /// <returns></returns>
        [NonAction]
        public void DelCacheKey(string cacheKey)
        {
            var res = _cache.GetString(CacheConst.KeyAll);
            var allkeys = string.IsNullOrWhiteSpace(res) ? new List<string>() : JSON.Deserialize<List<string>>(res);
            if (allkeys.Any(m => m == cacheKey))
            {
                allkeys.Remove(cacheKey);
                _cache.SetString(CacheConst.KeyAll, JSON.Serialize(allkeys));
            }
        }
        /// <summary>
        /// 获取所有缓存
        /// </summary>
        /// <returns></returns>
        public List<string> GetAllCacheKeys()
        {
            var res = _cache.GetString(CacheConst.KeyAll);
            return string.IsNullOrWhiteSpace(res) ? null : JSON.Deserialize<List<string>>(res);
        }
        /// <summary>
        /// 删除某特征关键字缓存
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        [NonAction]
        public void DelByPattern(string key)
        {
            var allkeys =  GetAllCacheKeys();
            if (allkeys == null) return;

            var delAllkeys = allkeys.Where(u => u.Contains(key)).ToList();
            delAllkeys.ForEach(u =>
            {
                _cache.Remove(u);
            });

            // 更新所有缓存键
            allkeys = allkeys.Where(u => !u.Contains(key)).ToList();
            _cache.SetString(CacheConst.KeyAll, JSON.Serialize(allkeys));
        }

       
    }
}
